<template>
    <div class="login_container" ref="loginContainer" @keyup.enter="handleEnter" tabindex="0">
        <div class="layer1"></div>
        <div class="layer2"></div>
        <div class="layer3"></div>
        <div class="layer4"></div>
        <div class="layer5"></div>
        <div class="layer6"></div>

        <el-form class="login_form" :model="loginForm" :rules="rules" ref="loginForms">
            <h1>登&nbsp;&nbsp;录</h1>
            <h2>欢迎来到实时聊天系统</h2>
            <el-form-item prop="username">
                <el-input
                    :prefix-icon="User"
                    v-model="loginForm.username"
                    placeholder="用户名"
                ></el-input>
            </el-form-item>
            <el-form-item prop="password">
                <el-input
                    type="password"
                    :prefix-icon="Lock"
                    v-model="loginForm.password"
                    show-password
                    placeholder="密码"
                ></el-input>
            </el-form-item>
            <el-form-item>
                <el-button
                    :loading="loading"
                    class="login_btn"
                    type="primary"
                    size="default"
                    @click="login"
                >
                    登录
                </el-button>
            </el-form-item>
            <el-form-item class="to-register">
                <span class="register" @click="toRegister">没有账号？前往注册</span>
            </el-form-item>
        </el-form>
    </div>
</template>

<script setup lang="ts">
import { User, Lock } from '@element-plus/icons-vue'
import { reactive, ref, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElNotification } from 'element-plus'
//引入获取当前时间的函数
import { getTime } from '@/utils/time'
//引入节流方法
import { throttle } from '@/utils/behaviorcontrol'
//引入用户相关的小仓库
import useUserStore from '@/store/modules/user'
import type { loginFormData } from '@/api/user/type'

//获取用户相关的小仓库
let useStore = useUserStore()
//获取路由器
let $router = useRouter()
//获取路由信息
let $route = useRoute()
//获取el-form组件
const loginForms = ref()
// 引用登录容器
const loginContainer = ref()
//定义变量控制按钮加载状态
let loading = ref<boolean>(false)
//收集账号与密码的数据
let loginForm = reactive<loginFormData>({ username: '', password: '' })

//登录按钮回调
const login = async () => {
    //保证全部表单校验通过再发请求
    await loginForms.value.validate()
    //加载效果，开始加载
    loading.value = true
    try {
        //保证登录成功
        await useStore.userLogin(loginForm)
        //判断是否有query参数，如果有则跳转到对应路径，没有则跳转到首页
        let redirect: any = $route.query.redirect
        //编程式导航跳转到首页
        $router.push({ path: redirect || '/' })
        //登录成功的提示信息
        ElNotification({
            type: 'success',
            message: '欢迎回来',
            title: `HI,${getTime()}好`,
        })
        //登录成功加载效果消失
        loading.value = false
    } catch (error) {
        //登录识别加载效果消失
        loading.value = false
        //登录失败的提示信息
        ElNotification({
            type: 'error',
            message: (error as Error).message,
        })
    }
}
//自定义校验规则函数
const validatorUserName = (_rule: any, value: any, callback: any) => {
    //rule即为数组校验规则对象，value为表单元素文本内容，符合条件callback放行通过，否则注入错误信息
    if (value.length >= 5 && value.length <= 10) {
        callback()
    } else {
        callback(new Error('账号长度至少为5位，至多为10位'))
    }
}
const validatorPassword = (_rule: any, value: any, callback: any) => {
    //rule即为数组校验规则对象，value为表单元素文本内容，符合条件callback放行通过，否则注入错误信息
    if (value.length >= 6 && value.length <= 15) {
        callback()
    } else {
        callback(new Error('密码长度至少为6位，至多为15位'))
    }
}
//定义表单检验配置对象
const rules = {
    username: [
        //required代表这个字段必须要检验，trigger是触发检验表单的时机
        { trigger: 'change', validator: validatorUserName },
    ],
    password: [{ trigger: 'change', validator: validatorPassword }],
}

//前往注册页
const toRegister = () => {
    //编程式导航跳转到注册页
    $router.push({ path: '/register' })
}

//对login方法进行节流处理
const throttledLogin = throttle(login, 1000) // 1秒的节流限制

//在按下Enter时调用节流后的登录方法
const handleEnter = (event: KeyboardEvent) => {
    if (event.key === 'Enter') {
        throttledLogin()
    }
}

onMounted(() => {
    // 页面加载时自动聚焦到登录容器
    loginContainer.value?.focus()
})
</script>

<style scoped lang="scss">
@function getShadows($n, $size) {
    $shadows:
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 0.3)} rgba(255, 255, 200, 0.8),
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 0.6)} rgba(255, 255, 200, 0.4),
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 1)} rgba(255, 255, 200, 0.2);

    @for $i from 2 through $n {
        $shadows:
            #{$shadows},
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 0.3)}
                rgba(255, 255, 200, 0.8),
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 0.6)}
                rgba(255, 255, 200, 0.4),
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 1)}
                rgba(255, 255, 200, 0.2);
    }

    @return $shadows;
}

$n: 18;
$size: 9px;

@for $j from 1 through 6 {
    .layer#{$j} {
        $size: calc($size - #{$j}px);
        $duration: calc(6s * #{$j});
        $n: floor(calc($n * pow(2, $j) / $j));
        position: fixed;
        width: $size;
        height: $size;
        border-radius: 50%;
        left: 0;
        top: 0;
        background-color: rgba(255, 255, 200, 0.8);
        box-shadow: getShadows($n, $size);
        animation: moveDown $duration linear infinite;

        &::after {
            content: '';
            position: fixed;
            width: $size;
            height: $size;
            border-radius: inherit;
            left: 0;
            top: 100vh;
            background-color: rgba(255, 255, 200, 0.8);
            box-shadow: inherit;
        }
    }
}

@keyframes moveDown {
    100% {
        transform: translateY(-100vh);
        opacity: 1;
    }

    50% {
        opacity: 0.2;
    }
}

.login_container {
    width: 100vw;
    height: 100vh;
    background: url('@/assets/images/background.jpg') no-repeat;
    background-size: cover;
    background-position: center;
    @include flex-layout(flex, center, center);
    overflow: hidden;
}

.login_form {
    width: 30vw;
    min-width: 300px;
    background-color: rgba(255, 255, 200, 0.4);
    background-size: cover;
    padding: 2.5rem;
    border-radius: 0.625rem;
}

h1 {
    color: white;
    font-size: 2.5rem;
    text-align: center;
}

h2 {
    color: white;
    font-size: 1.25rem;
    margin: 1.25rem 0;
    text-align: center;
}

.login_btn {
    width: 100%;
}

.to-register {
    margin-bottom: 0;
    cursor: pointer;

    .register {
        height: 1rem;
        line-height: 1rem;
        position: absolute;
        right: 0;
        color: white;
    }

    .register:hover {
        color: rgb(173, 216, 230);
        border-bottom: 2px solid rgb(173, 216, 230);
    }
}
</style>
